package com.googlecode.garbagecan.test.socket.sample7;

import com.googlecode.garbagecan.test.socket.IOUtil;

import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyServer {

	private final static Logger logger = Logger.getLogger(MyServer.class.getName());

	private int port;
	private boolean enableSSL;

	private ServerSocket serverSocket;

	public MyServer(int port, boolean enableSSL) {
		this.port = port;
		this.enableSSL = enableSSL;
	}

	public void start() throws Exception {
		if (enableSSL) {
			System.setProperty("javax.net.ssl.keyStore", MyServer.class.getResource("/com/googlecode/garbagecan/test/socket/ssl/mysocket.jks").getFile());
			System.setProperty("javax.net.ssl.keyStorePassword", "mysocket");
			ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
			serverSocket = factory.createServerSocket(port);
		} else {
			serverSocket = new ServerSocket(port);
		}

		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Socket socket = serverSocket.accept();
						invoke(socket);
					} catch (Exception e) {
						if (serverSocket != null && serverSocket.isClosed()) {
							break;
						}
						logger.log(Level.SEVERE, e.getMessage(), e);
					}
				}
			}
		}).start();
	}

	public void stop() throws Exception {
		serverSocket.close();
	}

	private void invoke(final Socket socket) throws Exception {
		new Thread(new Runnable() {
			public void run() {
				ObjectInputStream ois = null;
				ObjectOutputStream oos = null;
				
				try {
					ois = new ObjectInputStream(socket.getInputStream());
					oos = new ObjectOutputStream(socket.getOutputStream());
					while (true) {
						Object obj = ois.readObject();
						User user = (User)obj;
						//System.out.println("user: " + user.getName() + "/" + user.getPassword());

						user.setName(user.getName() + "_new");
						user.setPassword(user.getPassword() + "_new");

						oos.writeObject(user);
						oos.flush();
					}
				} catch (EOFException ex) {
					// logger.log(Level.SEVERE, ex.getMessage(), ex);
				} catch (Exception ex) {
					logger.log(Level.SEVERE, ex.getMessage(), ex);
				} finally {
					IOUtil.closeQuietly(ois);
					IOUtil.closeQuietly(oos);
					IOUtil.closeQuietly(socket);
				}
			}
		}).start();
	}

}
